<!DOCTYPE html>
<html>
<!--
Copyright 2008 The Closure Library Authors. All Rights Reserved.

Use of this source code is governed by an Apache 2.0 License.
See the COPYING file for details.
-->
<!--
  Author: zachlloyd@google.com (Zachary Lloyd)
-->
<head>
  <title>Closure Unit Tests - goog.net.MultiIframeLoadMonitor</title>
  <script src="../base.js"></script>
  <script>
    goog.require('goog.dom');
    goog.require('goog.events');
    goog.require('goog.net.MultiIframeLoadMonitor');
    goog.require('goog.testing.AsyncTestCase');
    goog.require('goog.testing.jsunit');
  </script>
</head>
<body>
<div id="frame_parent"></div>
<script>
  var TEST_FRAME_SRCS = ['iframeloadmonitor_test_frame.html',
      'iframeloadmonitor_test_frame2.html',
      'iframeloadmonitor_test_frame3.html'];

  // Create a new test case.
  var iframeLoaderTestCase = new goog.testing.AsyncTestCase(document.title);
  iframeLoaderTestCase.stepTimeout = 4 * 1000;

  // How many multpile frames finished loading
  iframeLoaderTestCase.multipleComplete_ = 0;

  iframeLoaderTestCase.numMonitors = 0;
  iframeLoaderTestCase.disposeCalled = 0;

  /** Sets up the test environment, adds tests and sets up the worker pools. */
  iframeLoaderTestCase.setUpPage = function() {
    this.log('Setting tests up');
    iframeLoaderTestCase.waitForAsync('loading iframes');

    var dom = goog.dom.getDomHelper();

    // Load multiple with callback
    var frame1 = dom.createDom('iframe');
    var frame2 = dom.createDom('iframe');
    var multiMonitor = new goog.net.MultiIframeLoadMonitor(
      [frame1, frame2], goog.bind(this.multipleCallback, this));
    this.log('Loading frames at: ' + TEST_FRAME_SRCS[0] + ' and '
        + TEST_FRAME_SRCS[1]);
    // Make sure they don't look loaded yet.
    assertEquals(0, this.multipleComplete_);
    var frameParent = dom.getElement('frame_parent');
    dom.appendChild(frameParent, frame1);
    frame1.src = TEST_FRAME_SRCS[0];
    dom.appendChild(frameParent, frame2);
    frame2.src = TEST_FRAME_SRCS[1];

    // Load multiple with callback and content check
    var frame3 = dom.createDom('iframe');
    var frame4 = dom.createDom('iframe');
    var multiMonitor = new goog.net.MultiIframeLoadMonitor(
      [frame3, frame4], goog.bind(this.multipleContentCallback, this), true);
    this.log('Loading frames with content check at: ' + TEST_FRAME_SRCS[1] +
        ' and ' + TEST_FRAME_SRCS[2]);
    dom.appendChild(frameParent, frame3);
    frame3.src = TEST_FRAME_SRCS[1];
    dom.appendChild(frameParent, frame4);
    frame4.src = TEST_FRAME_SRCS[2];

    this.add(new goog.testing.TestCase.Test(
        'test results', this.testResults, this));
    this.add(new goog.testing.TestCase.Test(
        'stopMonitoring', this.testStop, this));
  };


  /** Callback for the multiple frame load test case */
  iframeLoaderTestCase.multipleCallback = function() {
    this.log('multiple frames finished loading');
    this.multipleComplete_++;
    this.multipleCompleteNoContent_ = true;
    this.callbacksComplete();
  };

  /** Callback for the multiple frame with content load test case */
  iframeLoaderTestCase.multipleContentCallback = function() {
    this.log('multiple frames with content finished loading');
    this.multipleComplete_++;
    this.multipleCompleteContent_ = true;
    this.callbacksComplete();
  };

  /** Checks if all the load callbacks are done*/
  iframeLoaderTestCase.callbacksComplete = function() {
    if (this.multipleComplete_ == 2) {
      iframeLoaderTestCase.continueTesting();
    }
  }

  /** Tests the results. */
  iframeLoaderTestCase.testResults = function() {
    this.log('getting test results');
    assertTrue(this.multipleCompleteNoContent_);
    assertTrue(this.multipleCompleteContent_);
  };

  iframeLoaderTestCase.fakeLoadMonitor = function() {
    // Replaces IframeLoadMonitor with a fake version that just tracks
    // instantiations/disposals
    this.loadMonitorConstructor = goog.net.IframeLoadMonitor;
    var that = this;
    goog.net.IframeLoadMonitor = function() {
      that.numMonitors++;
      return {
        isLoaded: function() { return false; },
        dispose: function() { that.disposeCalled++; },
        attachEvent: function() {}
      };
    }
    goog.net.IframeLoadMonitor.LOAD_EVENT = 'ifload';
  };

  iframeLoaderTestCase.unfakeLoadMonitor = function() {
    goog.net.IframeLoadMonitor = this.loadMonitorConstructor;
  };


  iframeLoaderTestCase.testStop = function() {
    // create two unloaded frames, make sure that load monitors are loaded
    // behind the scenes, then make sure they are disposed properly.
    this.fakeLoadMonitor();
    var dom = goog.dom.getDomHelper();
    var frames = [dom.createDom('iframe'), dom.createDom('iframe')];
    var multiMonitor = new goog.net.MultiIframeLoadMonitor(
      frames,
      function() {
        fail("should not invoke callback for unloaded rames"); 
      });
    assertEquals(frames.length, this.numMonitors);
    assertEquals(0, this.disposeCalled);
    multiMonitor.stopMonitoring();
    assertEquals(frames.length, this.disposeCalled);
    this.unfakeLoadMonitor();
  };

  /** Used by the JsUnit test runner. */
  function testResults() {
    iframeLoaderTestCase.testResults();
  }

  /** Used by the JsUnit test runner. */
  function testDispose() {
    iframeLoaderTestCase.testDispose();
  }

  /** Used by the JsUnit test runner. */
  function setUpPage() {
    iframeLoaderTestCase.runTests();
  }

  /** Standalone Closure Test Runner. */
  if (typeof G_testRunner != 'undefined') {
    G_testRunner.initialize(iframeLoaderTestCase);
  }

</script>
</body>
</html>
